﻿#include "ArrangedText.h"
#include "Font/Glyph.h"

TVector<SVec2> SArrangedText::GetCharPositions() const
{
    TVector<SVec2> Result;
    Result.Reserve(Chars.Num());
    for(auto& Line: Lines)
    {
        for(int32_t CharIndex=Line.StartCharIndex;CharIndex<=Line.EndCharIndex;CharIndex++)
        {
            auto& Char=Chars[CharIndex];
            if(Char.Texture.HasValue())
            {
                SVec2 CharPosition;
                CharPosition.X=Line.XInRenderArea+Char.TextureXInLine;
                CharPosition.Y=Line.YInRenderArea+Char.TextureYInLine;
                Result.Add(CharPosition);
            }
        }
    }

    return Result;
}

TVector<SRenderCharTexture> SArrangedText::GetRenderCharTextures() const
{
    TVector<SRenderCharTexture> Result;
    Result.Reserve(Chars.Num());
    for(auto& Char: Chars)
    {
        if(Char.Texture.HasValue())
        {
            Result.Add(Char.Texture.GetValue().ToRenderTexture());
        }
    }

    return Result;
}

SVec2 SArrangedText::CalculateTextSize() const
{
    SVec2 TextSize;
    TextSize.X=0;
    TextSize.Y=0;

    for(auto& Line: Lines)
    {
        TextSize.X=CMathBase::Max(TextSize.X,Line.Width);
    }
 
    TextSize.Y=Lines.Num()*LineHeight;

    return TextSize;
}

int32_t SArrangedText::CalculateCursorIndex(const SVec2 &CursorPositionInRenderArea) const
{
    if(Lines.Empty())
    {
        return -1;
    }

    //找到光标所在的行
    int32_t LineIndex;
    if(CursorPositionInRenderArea.Y<=Lines[0].YInRenderArea)
    {
        LineIndex=0;
    }
    else if(CursorPositionInRenderArea.Y>=Lines.Last().YInRenderArea)
    {
        LineIndex=Lines.Num()-1;
    }
    else
    {
        for(LineIndex=0;LineIndex<Lines.Num();LineIndex++)
        {
            auto& Line=Lines[LineIndex];
            if(CursorPositionInRenderArea.Y>=Line.YInRenderArea && CursorPositionInRenderArea.Y<(Line.YInRenderArea+LineHeight))
            {
                break;
            }
        }
        assert(LineIndex<Lines.Num());
    }

    auto& Line=Lines[LineIndex];
    if(CursorPositionInRenderArea.X<=Line.XInRenderArea)
    {
        //光标在行的开头
        return Line.StartCharIndex-1;
    }
    else if(CursorPositionInRenderArea.X>=Line.XInRenderArea+Line.Width)
    {
        //光标在行的结尾
        return Line.EndCharIndex;
    }

    //找到光标所在的字符,光标在最终字符的右边
    for(int32_t CharIndex=Line.StartCharIndex;CharIndex<=Line.EndCharIndex;CharIndex++)
    {
        auto& Char=Chars[CharIndex];
        float CharCenterX=Char.Glyph->AdvanceX*0.5+Char.OcuppiedRectMinX +Line.XInRenderArea;
        if(CursorPositionInRenderArea.X<=CharCenterX)
        {
            return CharIndex-1;
        }

        if(CharIndex==Line.EndCharIndex)
        {
            return CharIndex;
        }
    }

    assert(false);
    return -1;
}

SRect SArrangedText::CalculateCursorRect(int32_t CursorPosition, float CursorWidth) const
{
    SRect CursorRect;
    CursorRect.Extent.X=CursorWidth;
    CursorRect.Extent.Y=LineHeight;

    if(Lines.Empty())
    {
        //根据对齐方式，计算光标的位置

        switch (Parameters.HorizontalAlign)
        {
            case ETextHorizontalAlignment::Scatter:
            case ETextHorizontalAlignment::Left:
            {
                CursorRect.Min.X=0;
                break;
            }

            case ETextHorizontalAlignment::Center:
            {
                CursorRect.Min.X= Parameters.PaintAreaSize.X*.5f-CursorWidth*.5f;
                break;
            }

            case ETextHorizontalAlignment::Right:
            {
                CursorRect.Min.X=Parameters.PaintAreaSize.X;
                break;
            }
        }

        switch(Parameters.VerticalAlign)
        {
            case ETextVerticalAlignment::Top:
            {
                CursorRect.Min.Y=0;
                break;
            }

            case ETextVerticalAlignment::Center:
            {
                CursorRect.Min.Y=(Parameters.PaintAreaSize.Y-LineHeight) *.5f;
                break;
            }

            case ETextVerticalAlignment::Bottom:
            {
                CursorRect.Min.Y=Parameters.PaintAreaSize.Y-LineHeight;
                break;
            }
        }

        return CursorRect;
    }


    if(CursorPosition<0)
    {
        //光标在行的开头
        CursorRect.Min.X=Lines[0].XInRenderArea;
        CursorRect.Min.Y=Lines[0].YInRenderArea;
        return CursorRect;
    }


    //找到光标所在的行
    int32_t LineIndex;
    for(LineIndex=0;LineIndex<Lines.Num();LineIndex++)
    {
        auto& Line=Lines[LineIndex];
        if(CursorPosition>=Line.StartCharIndex && CursorPosition<=Line.EndCharIndex)
        {
            break;
        }
    }
    assert(LineIndex<Lines.Num());

    auto& Line=Lines[LineIndex];
    CursorRect.Min.Y=Line.YInRenderArea;

    if(CursorPosition==Line.StartCharIndex-1)
    {
        //光标在行的开头
        CursorRect.Min.X=Line.XInRenderArea;
        return CursorRect;
    }

    if(CursorPosition==Line.EndCharIndex)
    {
        //光标在行(最后一行)的结尾
        CursorRect.Min.X=Line.XInRenderArea+Line.Width;
        return CursorRect;
    }

    auto& Char=Chars[CursorPosition+1]; //光标后面的字符
    CursorRect.Min.X=Char.OcuppiedRectMinX+Line.XInRenderArea;
    return CursorRect;

}

int32_t SArrangedText::GetRenderCharCount() const
{
    int32_t Count=0;
    for(auto& Char: Chars)
    {
        if(Char.Texture)
        {
            Count++;
        }
    }

    return Count;
}

bool SArrangedText::IsCharRendered(int32_t CharIndex) const
{
    return Chars[CharIndex].Texture;
}

SVec2 SArrangedText::GetRenderedCharRenderSize(int32_t CharIndex) const
{
    assert(IsCharRendered(CharIndex));
    return Chars[CharIndex].Glyph->Box.Extent;
}

SVec2 SArrangedText::GetRenderedCharPositionInImage(int32_t CharIndex) const
{
    assert(IsCharRendered(CharIndex));
    return SVec2(Chars[CharIndex].OffsetXInWholeImage,Chars[CharIndex].OffsetYInWholeImage);
}
